/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ifconnect.view.managedBean;

import ifconnect.model.dao.UsuarioDao;
import ifconnect.model.entity.Arquivo;
import ifconnect.model.entity.Comentario;
import ifconnect.model.entity.Disciplina;
import ifconnect.model.entity.Postagem;
import ifconnect.model.entity.Turma;
import ifconnect.model.entity.Usuario;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import javax.el.MethodExpression;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.imageio.stream.FileImageOutputStream;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.MenuModel;
import org.primefaces.model.StreamedContent;

/**
 *
 * @author Fidélis
 */
@ManagedBean(name = "usuariologin")
@SessionScoped
public class UsuarioLoginMB implements Serializable {

    private UsuarioDao usuarioDao;
    private Usuario usuario;
    private List<Usuario> cadastrosPendentes;
    ArrayList<Comentario> comPost;
    private Usuario moderando;
    private String email, senha, senhaatual, novasenha1, novasenha2, conteudoPostagem;
    private boolean mostrarAviso1, mostrarAviso2;
    private List<Turma> turmas;
    private List<Postagem> listaPostagens;
    private List<Comentario> listaComentarios;
    private List<String> disciplinasSelecionadas;
    private List<Disciplina> disciplinasExistentes;
    private Long turmaSelecionada;
    private Disciplina disciplinaSelecionada;
    private Disciplina disciplinaPagina;
    private MenuModel model;
    private StreamedContent file;
    private Collection<Arquivo> arquivosDisciplinas;
    private String textImplace = "";

    public UsuarioLoginMB() {
        this.usuarioDao = new UsuarioDao();
    }

    public String logout() {
        String retorno = "/index.xhtml?faces-redirect=true";

        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        HttpSession session = (HttpSession) externalContext.getSession(true);
        Usuario sessao = (Usuario) session.getAttribute("usuario");
        if (sessao != null) {
            session.removeAttribute("usuario");
            session.invalidate();
        }
        return retorno;
    }

    public String login() {
        this.usuarioDao = new UsuarioDao();
        this.usuario = usuarioDao.verificarLogin(email, senha);

        if (this.usuario != null && this.usuario.getStatus().equals("A")) {

            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            HttpSession session = (HttpSession) externalContext.getSession(false);
            session.setAttribute("usuario", this.usuario);

            //USUÁRIO É UM ADMINISTRADOR
            if (this.usuario.getTipo().equals("AD")) {
                this.verificarCadastrosPendentes();
                return "/admin/principalAdmin.xhtml";
                //USUÁRIO É UM PROFESSOR
            } else if (this.usuario.getTipo().equals("PF")) {
                return "";
                //USUÁRIO É UM ALUNO
            } else if (this.usuario.getTipo().equals("AL")) {
                this.carregarConfiguracoes();
                this.criarMenuAluno();
                return "/usuario/principalUsuario.xhtml";
            }
        } else {
            FacesMessage msg = new FacesMessage("Erro no login!");
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return "/index.xhtml";
        }
        FacesMessage msg = new FacesMessage("Num sei o erro!");
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext.getCurrentInstance().addMessage(null, msg);
        return "/index.xhtml";
    }

    public String carregaCadastrosPendentes() {
        this.cadastrosPendentes = this.usuarioDao.getCadastrosPendentes();
        return "paginaGerenciarAcesso.xhtml";
    }

    private void carregarConfiguracoes() {
        if (this.disciplinasExistentes == null) {
            this.disciplinasExistentes = this.usuarioDao.listarTodos(Disciplina.class);
        }

        if (turmas == null) {
            this.turmas = this.usuarioDao.listarTodos(Turma.class);
        }
    }

    public String gereciarAcesso(Long id) {
        for (Iterator<Usuario> it = cadastrosPendentes.iterator(); it.hasNext();) {
            Usuario outro = it.next();
            if (outro.getId() == id) {
                this.moderando = outro;
            }
        }
        return "paginaGerenciarUsuario.xhtml";
    }

    public void aceitarUsuario() {
        int retorno = this.usuarioDao.mudarStatus("A", this.moderando.getId());
        FacesMessage message = null;
        if (retorno == 1) {
            message = new FacesMessage("Usuário habilitado ao acesso com sucesso!");
            message.setSeverity(FacesMessage.SEVERITY_INFO);
        } else {
            message = new FacesMessage("Erro ao gerenciar acesso do Usuário!");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
        }

        FacesContext.getCurrentInstance().addMessage(null, message);

        this.cadastrosPendentes = this.usuarioDao.getCadastrosPendentes();
        this.verificarCadastrosPendentes();

    }

    public void recusarUsuario() {
        int retorno = this.usuarioDao.mudarStatus("R", this.moderando.getId());
        FacesMessage message = null;
        if (retorno == 1) {
            message = new FacesMessage("Usuário recusado ao acesso com sucesso!");
            message.setSeverity(FacesMessage.SEVERITY_INFO);
        } else {
            message = new FacesMessage("Erro ao gerenciar acesso do Usuário!");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
        }

        FacesContext.getCurrentInstance().addMessage(null, message);

        this.cadastrosPendentes = this.usuarioDao.getCadastrosPendentes();
        this.verificarCadastrosPendentes();
    }

    public void alterarSenha() {
        FacesMessage message = null;
        if (this.senhaatual.equals(this.usuario.getSenha())) {
            if (this.novasenha1.equals(this.novasenha2)) {
                this.usuario.setSenha(this.novasenha1);
                this.usuarioDao.atualizar(this.usuario);
                message = new FacesMessage("Senha alterada com sucesso!");
                message.setSeverity(FacesMessage.SEVERITY_INFO);
            } else {
                message = new FacesMessage("Preencha os campo de confirmação de senha corretamente!");
                message.setSeverity(FacesMessage.SEVERITY_ERROR);
            }
        } else {
            message = new FacesMessage("Senha atual incorreta!");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
        }
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    private void verificarCadastrosPendentes() {
        this.carregaCadastrosPendentes();
        if (this.cadastrosPendentes.isEmpty()) {
            this.mostrarAviso1 = true;
            this.mostrarAviso2 = false;
        } else {
            this.mostrarAviso1 = false;
            this.mostrarAviso2 = true;
        }
    }

    public String atualizaDadosContaUsuario() {
        this.usuarioDao = new UsuarioDao();
        String msg = this.usuarioDao.atualizar(this.usuario);
        FacesMessage message = new FacesMessage(msg);
        message.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(null, message);

        return "paginaConfigurarPerfil.xhtml";
    }

    public String downloadFile(Arquivo a) {

        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        ServletContext servletContext = (ServletContext) context.getContext();

        //Obtem o caminho para o arquivo e efetua a leitura
        byte[] arquivo = readFile(new File(servletContext.getRealPath("") + a.getUrl()));
        HttpServletResponse response = (HttpServletResponse) context.getResponse();
        //configura o arquivo que vai voltar para o usuario.
        response.setHeader("Content-Disposition", "attachment;filename=\"" + a.getNome() + "\"");
        response.setContentLength(arquivo.length);
        //isso faz abrir a janelinha de download
        response.setContentType(a.getTipo());
        //envia o arquivo de volta
        try {
            OutputStream out = response.getOutputStream();
            out.write(arquivo);
            out.flush();
            out.close();
            FacesContext.getCurrentInstance().responseComplete();
        } catch (IOException e) {
            System.out.print("Erro no envio do arquivo");
            e.printStackTrace();
        }
        return "";

    }

    //efetua a leitura do arquivo
    public static byte[] readFile(File file) {
        int len = (int) file.length();
        byte[] sendBuf = new byte[len];
        FileInputStream inFile = null;
        try {
            inFile = new FileInputStream(file);
            inFile.read(sendBuf, 0, len);

        } catch (FileNotFoundException e) {
            System.out.print("Arquivo não encontrado");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.print("Erro na leitura do arquivo");
            e.printStackTrace();
        }
        return sendBuf;
    }

    public void fileUploadActionArquivo(FileUploadEvent event) {
        Calendar c = new GregorianCalendar();
        String[] partesNome = event.getFile().getFileName().split("\\.");

        String nomeArq = "arquivo" + this.usuario.getId() + "_" + c.get(Calendar.DAY_OF_MONTH) + c.get(Calendar.MONTH) + c.get(Calendar.YEAR) + "_" + c.get(Calendar.HOUR) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND) + "." + partesNome[1];

        ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
        String newFileName = servletContext.getRealPath("") + File.separator + "resources" + File.separator + "arquivos" + File.separator + nomeArq;

        FileImageOutputStream imageOutput;
        try {
            Arquivo a = new Arquivo();
            a.setNome(nomeArq);
            a.setUrl(File.separator + "resources" + File.separator + "arquivos" + File.separator + nomeArq);
            a.setTipo(event.getFile().getContentType());
            a.setDataHora(new Date());

            Collection<Arquivo> arquivos = this.disciplinaPagina.getArquivos();

            arquivos.add(a);

            this.disciplinaPagina.setArquivos(arquivos);
            this.usuarioDao.atualizar(this.disciplinaPagina);

            imageOutput = new FileImageOutputStream(new File(newFileName));
            imageOutput.write(event.getFile().getContents(), 0, event.getFile().getContents().length);
            imageOutput.close();

            FacesMessage message = new FacesMessage("ARQUIVO ENVIADO COM SUCESSO!");
            message.setSeverity(FacesMessage.SEVERITY_INFO);
            FacesContext.getCurrentInstance().addMessage(null, message);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void fileUploadAction(FileUploadEvent event) {

        if (this.usuario.getFoto().equals("user-profile.jpg")) {
            Calendar c = new GregorianCalendar();
            String[] partesNome = event.getFile().getFileName().split("\\.");

            String nomeArq = "usuario" + this.usuario.getId() + "_" + c.get(Calendar.DAY_OF_MONTH) + c.get(Calendar.MONTH) + c.get(Calendar.YEAR) + "_" + c.get(Calendar.HOUR) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND) + "." + partesNome[1];

            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
            String newFileName = servletContext.getRealPath("") + File.separator + "resources" + File.separator + "usuario" + File.separator + nomeArq;

            FileImageOutputStream imageOutput;
            try {

                this.usuario.setFoto(nomeArq);


                imageOutput = new FileImageOutputStream(new File(newFileName));
                imageOutput.write(event.getFile().getContents(), 0, event.getFile().getContents().length);
                imageOutput.close();


            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
            String caminhoAtualizando = servletContext.getRealPath("") + File.separator + "resources" + File.separator + "usuario" + File.separator + this.usuario.getFoto();

            FileImageOutputStream imageOutput;
            try {


                imageOutput = new FileImageOutputStream(new File(caminhoAtualizando));
                imageOutput.write(event.getFile().getContents(), 0, event.getFile().getContents().length);
                imageOutput.close();


            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public void atualizarTurmaAluno() {
        if (this.turmaSelecionada != null) {
            for (Iterator<Turma> it = turmas.iterator(); it.hasNext();) {
                Turma turma = it.next();
                if (turma.getId().equals(this.turmaSelecionada)) {
                    this.usuario.setTurma(turma);
                }
            }
        }

        String msg = this.usuarioDao.atualizar(usuario);

        FacesMessage message = new FacesMessage(msg);
        message.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public void atualizarDisciplinasAluno() {
        boolean flag = true;

        Collection<Disciplina> disciplinasNovas = new ArrayList<Disciplina>();

        for (Iterator<String> it = disciplinasSelecionadas.iterator(); it.hasNext();) {
            String sid = it.next();
            Long id = new Long(sid);
            for (Iterator<Disciplina> it1 = disciplinasExistentes.iterator(); it1.hasNext();) {
                Disciplina disciplina = it1.next();
                if (disciplina.getId().equals(id)) {
                    disciplinasNovas.add(disciplina);
                }
            }
        }

        Usuario novo = this.usuarioDao.cadastrarDisciplina(usuario, disciplinasNovas);
        if (novo != null) {
            this.usuario = novo;
        } else {
            flag = false;
        }
        String msg = "Informações do Usuário atualizado com sucesso!";
        if (!flag) {
            msg = "Erro ao atualizar informações do Usuário";
        }

        this.criarMenuAluno();

        FacesMessage message = new FacesMessage(msg);
        message.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    private void criarMenuAluno() {
        model = new DefaultMenuModel();

        MenuItem item = new MenuItem();
        item.setIcon("ui-icon-home");
        item.setValue("Home");
        item.setOutcome("principalUsuario.xhtml");

        model.addMenuItem(item);

        item = new MenuItem();
        item.setIcon("ui-icon-star");
        item.setValue("Campus");
        item.setOutcome("paginaVerCampus.xhtml");

        model.addMenuItem(item);

        item = new MenuItem();
        item.setIcon("ui-icon-star");
        item.setValue("Curso");
        item.setOutcome("paginaVerCurso.xhtml");

        model.addMenuItem(item);

        Submenu submenu = new Submenu();
        submenu.setLabel("Disciplinas");

        for (Iterator<Disciplina> it = usuario.getDisciplinas().iterator(); it.hasNext();) {
            Disciplina disciplina = it.next();
            item = new MenuItem();
            item.setValue(disciplina.getNome());
            String action = "#{usuariologin.montaPaginaDisciplina(" + disciplina.getId() + ")}";
            MethodExpression methodExpression = FacesContext
                    .getCurrentInstance()
                    .getApplication()
                    .getExpressionFactory()
                    .createMethodExpression(
                    FacesContext.getCurrentInstance().getELContext(),
                    action, null, new Class<?>[0]);
//            item.setOutcome("#");  
            item.setActionExpression(methodExpression);
            submenu.getChildren().add(item);
        }

        model.addSubmenu(submenu);

    }

    public String montaPaginaDisciplina(String id) {
        Long idl = Long.valueOf(id);
        for (Iterator<Disciplina> it = usuario.getDisciplinas().iterator(); it.hasNext();) {
            Disciplina disciplina = it.next();
            if (disciplina.getId().equals(idl)) {
                this.disciplinaPagina = disciplina;
                this.arquivosDisciplinas = disciplina.getArquivos();
            }
        }
        return "paginaVerDisciplina.xhtml";
    }

    public Collection<Arquivo> getArquivosDisciplinas() {
        return arquivosDisciplinas;
    }

    public StreamedContent getFile() {
        return file;
    }

    public Disciplina getDisciplinaPagina() {
        return disciplinaPagina;
    }

    public void setDisciplinaPagina(Disciplina disciplinaPagina) {
        this.disciplinaPagina = disciplinaPagina;
    }

    public MenuModel getModel() {
        return model;
    }

    public Disciplina getDisciplinaSelecionada() {
        return disciplinaSelecionada;
    }

    public void setDisciplinaSelecionada(Disciplina disciplinaSelecionada) {
        this.disciplinaSelecionada = disciplinaSelecionada;
    }

    public List<Disciplina> getDisciplinasExistentes() {
        return disciplinasExistentes;
    }

    public void setDisciplinasExistentes(List<Disciplina> disciplinasExistentes) {
        this.disciplinasExistentes = disciplinasExistentes;
    }

    public List<String> getDisciplinasSelecionadas() {
        return disciplinasSelecionadas;
    }

    public void setDisciplinasSelecionadas(List<String> disciplinasSelecionadas) {
        this.disciplinasSelecionadas = disciplinasSelecionadas;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public Usuario getUsuario() {
        return usuario;
    }

    public void setUsuario(Usuario usuario) {
        this.usuario = usuario;
    }

    public Long getTurmaSelecionada() {
        return turmaSelecionada;
    }

    public void setTurmaSelecionada(Long turmaSelecionada) {
        this.turmaSelecionada = turmaSelecionada;
    }

    public List<Usuario> getCadastrosPendentes() {
        return cadastrosPendentes;
    }

    public void setCadastrosPendentes(List<Usuario> cadastrosPendentes) {
        this.cadastrosPendentes = cadastrosPendentes;
    }

    public List<Turma> getTurmas() {
        return turmas;
    }

    public void setTurmas(List<Turma> turmas) {
        this.turmas = turmas;
    }

    public Usuario getModerando() {
        return moderando;
    }

    public void setModerando(Usuario moderando) {
        this.moderando = moderando;
    }

    public String getNovasenha1() {
        return novasenha1;
    }

    public void setNovasenha1(String novasenha1) {
        this.novasenha1 = novasenha1;
    }

    public String getNovasenha2() {
        return novasenha2;
    }

    public void setNovasenha2(String novasenha2) {
        this.novasenha2 = novasenha2;
    }

    public String getSenhaatual() {
        return senhaatual;
    }

    public void setSenhaatual(String senhaatual) {
        this.senhaatual = senhaatual;
    }

    public boolean isMostrarAviso1() {
        return mostrarAviso1;
    }

    public void setMostrarAviso1(boolean mostrarAviso1) {
        this.mostrarAviso1 = mostrarAviso1;
    }

    public boolean isMostrarAviso2() {
        return mostrarAviso2;
    }

    public void setMostrarAviso2(boolean mostrarAviso2) {
        this.mostrarAviso2 = mostrarAviso2;
    }
    
    public String getTextImplace() {
        return textImplace;
    }

    public void setTextImplace(String textImplace) {
        this.textImplace = textImplace;
    }

    public void setrTextImplace(String textImplace) {
        this.textImplace = textImplace;
    }

    public String getConteudoPostagem() {
        return conteudoPostagem;
    }

    public void setConteudoPostagem(String conteudoPostagem) {
        this.conteudoPostagem = conteudoPostagem;
    }

    public void fazpostagem() {
        Postagem p = new Postagem();
        p.setDataHora(new Date());
        p.setConteudo(conteudoPostagem);
        p.setUsuario(usuario);
        usuarioDao.salvar(p);
        p = new Postagem();
        conteudoPostagem = null;
    }
    
    public void fazComentario(Postagem p) {
        Comentario coment = new Comentario();
        coment.setConteudo(this.textImplace);
        coment.setUsuario(usuario);
        coment.setPostagem(p);
        
        usuarioDao.salvar(coment);
        this.textImplace = "";
    }

    public List<Postagem> getListaPostagens() {
        listaPostagens = usuarioDao.getPostagemUsuario(usuario);
        return listaPostagens;
    }

    public ArrayList<Comentario> getComPost() {
        return comPost;
    }

    public void setComPost(ArrayList<Comentario> comPost) {
        this.comPost = comPost;
    }

    public List<Comentario> getListaComentarioPorPostagens(Postagem ps) {
        comPost = (ArrayList<Comentario>) usuarioDao.getComentarioPorPostagem(ps);
        return comPost;
    }

    
    public void setListaPostagens(List<Postagem> listaPostagens) {
        this.listaPostagens = listaPostagens;
    }

    public List<Comentario> getListaComentarios(long post) {
        listaComentarios = usuarioDao.getComentarioPostagem(post);
        return listaComentarios;
    }

    public void setListaComentarios(List<Comentario> listaComentarios) {
        this.listaComentarios = listaComentarios;
    }

    private void fazComentario() {
    }
}
